package com.qmrz.nb.common.util;
//
import com.qmrz.nb.common.domain.Excel;
import com.qmrz.nb.common.domain.ExcelSheet;
//import cn.quevo.xuanniao.core.lang.NumberUtils;
//import cn.quevo.xuanniao.core.util.JsonUtil;
import org.apache.commons.lang3.math.NumberUtils;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;

import cn.hutool.core.convert.Convert;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import cn.hutool.core.util.NumberUtil;

public class MachineFaultTools {

    private static  Integer[] arr = {0,4,8,9};

    public List<Map<String, String>> merge(String preFile, InputStream preInputStream, String curFile, InputStream curInputStream) throws IOException {
        Excel preExcel = null;
        Excel curExcel = null;
        try {
            preExcel = new Excel(preFile, preInputStream);
            curExcel = new Excel(curFile, curInputStream);
            ExcelSheet excelSheet = new ExcelSheet();
            excelSheet.setbeginDataIndex(3);
            excelSheet.setSheetIndex(1);
            List<List<String>> preData = excelSheet.readData(preExcel);
            List<List<String>> curData = excelSheet.readData(curExcel);
            List<Map<String, String>> mergeData = new ArrayList<>();
            for (int r = 0; r < preData.size(); r++) {
                if ("合计".equalsIgnoreCase(preData.get(r).get(0))) {
                    Map<String, String> map = new HashMap();
                    final Integer cur1 = Convert.toInt(curData.get(r).get(3));
                    final Integer cur2 = Convert.toInt(curData.get(r).get(4));
                    map.put("diff10", (cur1 - cur2) + "");
                    map.put("diff11", ( Convert.toInt(curData.get(r).get(5)) - Convert.toInt(curData.get(r).get(6)) ) + "");
                    map.put("diff12", ( Convert.toInt(curData.get(r).get(7)) - Convert.toInt(curData.get(r).get(8)) ) + "");
                    map.put("diff13", ( Convert.toInt(curData.get(r).get(9)) - Convert.toInt(curData.get(r).get(10)) ) + "");
                    map.put("diff14", ( Convert.toInt(curData.get(r).get(11)) - Convert.toInt(curData.get(r).get(12)) ) + "");
                    map.put("diff15", ( Convert.toInt(curData.get(r).get(13)) - Convert.toInt(curData.get(r).get(14)) ) + "");
                    map.put("diff16", ( Convert.toInt(curData.get(r).get(15)) - Convert.toInt(curData.get(r).get(16)) ) + "");
                    map.put("diff17", ( Convert.toInt(curData.get(r).get(17)) - Convert.toInt(curData.get(r).get(18)) ) + "");
                    map.put("diff18", ( Convert.toInt(curData.get(r).get(19)) - Convert.toInt(curData.get(r).get(20)) ) + "");
                    mergeData.add(map);
                    break;
                }
                if ( "".equalsIgnoreCase(preData.get(r).get(0))) {
                    break;
                }
                if(Arrays.asList(arr).contains(r)){
                    mergeData.add(this.mergeRowData(preData.get(r), curData.get(r)));
                }
            }
            double a = 1.0; // 我下断点的地方，打在下一行的话 我怕看不见mergeData了
            return mergeData;
        } finally {
            if (preExcel != null) {
                preExcel.close();
            }
            if (curExcel != null) {
                curExcel.close();
            }
        }
    }

    private Map<String, String> mergeRowData(List<String> preRow, List<String> curRow) {
        Map<String, String> mergeRow = new HashMap();
        int propIndex = 10;
        mergeRow.put("name", preRow.get(0));
        int preTotal = 0;
        int curTotal = 0;
        int num = 0;
        num = getRealValue(preRow, 1, true);
        preTotal += num;
        mergeRow.put("vp" + propIndex, num+"");
        num = getRealValue(curRow, 1, true);
        curTotal += num;
        mergeRow.put("vc" + propIndex, num+"");
        propIndex ++;
        for (int colIndex = 5; colIndex < 21; colIndex += 2) {
            num = getRealValue(preRow, colIndex, false);
            preTotal += num;
            mergeRow.put("vp" + propIndex, num + "");
            num = getRealValue(curRow, colIndex, false);
            curTotal += num;
            mergeRow.put("vc" + propIndex, num+"");
            propIndex ++;
        }
        mergeRow.put("preTotal", preTotal+"");
        mergeRow.put("curTotal", curTotal+"");
        if (preTotal == 0) {
            mergeRow.put("growth", curTotal == 0 ? "0" : "100");
        }else {
            // 保留2 位小数的写法
            mergeRow.put("growth", NumberUtil.round( (curTotal - preTotal) * 100d /preTotal, 2) + ""  );
        }
        return mergeRow;
    }

    private int getRealValue(List<String> rowData, int colIndex, boolean isTicket) {
        int num = NumberUtils.toInt(rowData.get(colIndex)) ;
        if (isTicket) {
            num += NumberUtils.toInt(rowData.get(colIndex + 3)) ;
        }
        return num;
    }

    public Map<String, String> mergeSum(List<Map<String,String>> data) {
        Map<String, String> sum = new LinkedHashMap<>();
        for (int i = 10; i < 19; i ++) {
            final String pkey = "vp"+i;
            final String ckey = "vc"+i;
            sum.put(pkey,data.stream().mapToInt(map -> NumberUtils.toInt(map.get(pkey))).sum()+"");
            sum.put(ckey,data.stream().mapToInt(map -> NumberUtils.toInt(map.get(ckey))).sum()+"");
        }
        int preTotal = data.stream().mapToInt(map -> NumberUtils.toInt(map.get("preTotal"))).sum();
        int curTotal = data.stream().mapToInt(map -> NumberUtils.toInt(map.get("curTotal"))).sum();
        sum.put("preTotal",preTotal+"");
        sum.put("curTotal",curTotal+"");
        if (preTotal == 0) {
            sum.put("growth", curTotal == 0 ? "0" : "100");
        }else {
            // 保留2位小数的写法
            sum.put("growth", NumberUtil.round( (curTotal - preTotal) * 100d /preTotal, 2) + ""  );
        }
        return sum;
    }


    public Map<String, String> proportionSumHelp( Map<String, String> sumList , List<Map<String,String>> data) {
        Integer ptotal = NumberUtils.toInt(sumList.get("vp10"));
        Integer ctotal = NumberUtils.toInt(sumList.get("vc10"));
        if( ptotal - ctotal > 0) {
            sumList.put("pcFont10","有下降");
            sumList.put("pc10","下降" + (NumberUtil.round( (ptotal - ctotal) * 100d /ptotal, 2)) + "%");
        }else if ( ptotal - ctotal == 0) {
            sumList.put("pcFont10","持平");
            sumList.put("pc10","持平");
        }else {
            sumList.put("pcFont10","有上升");
            sumList.put("pc10","上升" + (NumberUtil.round( (ctotal - ptotal) * 100d /ptotal, 2)) + "%");
        }
        // 环比率

        // 11 电扶梯处理的情况
        Integer ptotal1 = NumberUtils.toInt(sumList.get("vp11"));
        Integer ctotal1= NumberUtils.toInt(sumList.get("vc11"));
        if( ptotal1 - ctotal1 > 0) {
            sumList.put("pc11", "减少了" +  Math.abs(ptotal1 - ctotal1)  + "起");
        }else if ( ptotal1 - ctotal1 == 0 ){
            sumList.put("pc11","持平");
        }else{
            sumList.put("pc11", "增加了" +  Math.abs(ptotal1 - ctotal1)  + "起");
        }
        sumList = this.setMaxVpc(sumList,data,"11"); // 取最高故障的数据

        // 12 站台门的情况
        // 取最高故障的数据
        sumList = this.setMaxVpc(sumList,data,"12"); // 取最高故障的数据

        // 13 FAS系统
        // 取最高故障的数据
        sumList = this.setCompare(sumList, data,"13");
        sumList = this.setMaxVpc(sumList,data,"13"); // 取最高故障的数据

        // 14 BAS问题
        // 取最高故障的数据
        sumList = this.setCompare(sumList, data,"14");
        sumList = this.setMaxVpc(sumList, data,"14"); // 取最高故障的数据
        
        // 15 给排水问题
        sumList = this.setCompare(sumList, data,"15");
        sumList = this.setMaxVpc(sumList,data,"15"); // 取最高故障的数据


        // 16 环控专业
        Integer ptotal16 = NumberUtils.toInt(sumList.get("vp16"));
        Integer ctotal16 = NumberUtils.toInt(sumList.get("vc16"));
        if( ptotal16 - ctotal16 > 0) {
            sumList.put("pc16","比上月下降" + (ptotal16 - ctotal16) +"起");
            //sumList.put("","下降" + (NumberUtil.round( (ptotal16 - ctotal16) * 100d /ptotal16, 2)) + "%");
        }else if ( ptotal16 - ctotal16 == 0) {
            sumList.put("pc16","比上月" + ptotal16 +"起持平");
        }else {
            Integer diff = ctotal16 - ptotal16;
            sumList.put("pc16","比上月上升" + diff +"起");
            if(diff>20){
                sumList.put("pc16","比上月上升" + diff +"起，上升较多");
            }

        }

        // 17 低压配电专业
        sumList = this.setCompare(sumList, data,"17");
        sumList = this.setMaxVpc(sumList,data,"17"); // 取最高故障的数据

        // 18 房建专业
        sumList = this.setCompare(sumList, data,"18");
        sumList = this.setMaxVpc(sumList,data,"18"); // 取最高故障的数据

        return sumList;
    }

    public List<Map<String,String>> proportionHelp(List<Map<String,String>> data, Map<String, String> sumList) {
        String[] arr = { "10","11","12","13","14","15","16","17","18"};

        for(int j =0; j<arr.length ; j++ ) {
            Integer ctotal = NumberUtils.toInt(sumList.get("vc" + arr[j]));
            for(int i = 0 ; i<data.size();i++) {
                Integer vc10 = NumberUtils.toInt(data.get(i).get("vc"  + arr[j] ));
                if(ctotal == 0) {
                    data.get(i).put("vcp" + arr[j], 0 + "");
                }else{
                    data.get(i).put("vcp" + arr[j], NumberUtil.round( vc10 * 100d /ctotal, 2) + "");
                }

            }
        }
        return data;
    }


    // 计算环比
    public Map<String, String> setCompare(Map<String, String> sumList ,List<Map<String,String>> data ,String number) {
        Integer ptotal15 = NumberUtils.toInt(sumList.get("vp" + number));
        Integer ctotal15 = NumberUtils.toInt(sumList.get("vc" + number));
        if( ptotal15 - ctotal15 > 0) {
            sumList.put("pc" + number, "下降" + (NumberUtil.round( (ptotal15 - ctotal15) * 100d /ptotal15, 2)) + "%");
        }else if ( ptotal15 - ctotal15 == 0) {
            sumList.put("pc" + number, "持平");
        }else {
            sumList.put("pc" + number, "上升" + (NumberUtil.round( (ctotal15 - ptotal15) * 100d /ptotal15, 2)) + "%");
        }
        return sumList;
    }

    // 取最高故障的数据
    public Map<String, String> setMaxVpc(Map<String, String> sumList ,List<Map<String,String>> data ,String number) {
        double vcp12 = 0;
        int vpc12Index = 0;
        for(int i = data.size()-1 ; i >= 0;i--) {
            if ( Convert.toDouble(data.get(i).get("vcp" + number )) > vcp12 ){
                vcp12 = Convert.toDouble(data.get(i).get("vcp" + number ));
                vpc12Index = i;
            }
        }
        sumList.put("top" + number, data.get(vpc12Index).get("name") + "");
        sumList.put("tp" + number , vcp12 + "");

        // 如果数值都是最大 要用中文顿号链接 1、9号线
        List<Integer> list = new ArrayList<>();
        for(int i = 0 ; i<data.size();i++) {
            if ( Convert.toDouble(data.get(i).get("vcp" + number )) == vcp12 ){
                if(vpc12Index != i) {
                    list.add(i);
                }
            }
        }
        if(list.size()>0){
            String str = "";
            for(int key : list) {
                str += data.get(key).get("name").replace("号线","、");
            }
            sumList.put("top" + number, str + data.get(vpc12Index).get("name") );
        }
        return sumList;
    }

    public static void main(String[] args) throws IOException {
        MachineFaultTools tools = new MachineFaultTools();
        List<Map<String,String>> data = tools.merge("6月 运一附件1：运营设施设备月度统计数据.xlsx", Files.newInputStream(Paths.get("F:\\projects\\霏霏\\运一，上海地铁生成docx一期简单的需求文档\\6月 运一附件1：运营设施设备月度统计数据.xlsx")), "7月 运一附件1：运营设施设备月度统计数据.xlsx", Files.newInputStream(Paths.get("F:\\projects\\霏霏\\运一，上海地铁生成docx一期简单的需求文档\\7月 运一附件1：运营设施设备月度统计数据.xlsx")));

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy(true);
        Configure config = Configure.builder()
            .bind("merge", policy).build();
        XWPFTemplate template = XWPFTemplate.compile("F:\\projects\\霏霏\\运一，上海地铁生成docx一期简单的需求文档\\template.docx", config).render(
            new HashMap<String, Object>(){{
                put("t", tools.mergeSum(data));
                put("merge", data);
            }});
        template.writeAndClose(new FileOutputStream("F:\\projects\\霏霏\\运一，上海地铁生成docx一期简单的需求文档\\test.docx"));
//        System.out.println(JsonUtil.format(data));
    }
}
